/**
 * SpeedStatistics.java
 * @author: liuex
 * 2007-12-30 ����10:34:12
 *
 * note: 
 */
package org.lex.utils;

import java.util.ArrayDeque;
import java.util.Deque;

public class SpeedStatistics {
	private static final long DEFAULT_AGE = 1000 * 60 * 5;// 5 minutes
	private Deque<Sample> data = null;
	private long startTime = 0L;
	private long stopTime = 0L;
	private boolean stop = false;
	private long age = 0L;

	public SpeedStatistics() {
		this(DEFAULT_AGE);
	}

	public SpeedStatistics(long interval) {
		this.age = interval;
		data = new ArrayDeque<Sample>();
	}

	public void start() {
		this.startTime = System.currentTimeMillis();
		this.stop = false;
		data.clear();
	}

	public void stop() {
		this.stop = true;
		this.stopTime = System.currentTimeMillis();
	}

	public void addSample(long length) {
		this.data.offerFirst(new Sample(length));
		this.removeOldSamples();
	}

	public long getAverage() {
		if (true == stop) {
			long time = stopTime - startTime;
			if (0 == time)
				return -1L;
			else
				return data.peekLast().value * 1000 / time;
		}
		long time = System.currentTimeMillis() - this.startTime;
		if (0 == time)
			return -1L;
		return data.peekLast().value * 1000 / time;
	}

	public long getRecentAverage() {
		long time = data.peekLast().time - data.peekFirst().time;
		if (0 == time)
			return -1;

		return (data.peekLast().value - data.peekFirst().value) * 1000 / time;
	}

	private void removeOldSamples() {
		long current = System.currentTimeMillis();
		while (false == data.isEmpty()) {
			Sample a = data.peekFirst();
			if (null == a)
				return;
			if (current - a.time >= age)
				data.pollFirst();
		}
	}

	static class Sample {
		long time = 0L;
		long value = 0L;

		Sample(long length) {
			this.time = System.currentTimeMillis();
			this.value = length;
		}
	}
}
